package io.jft.doll.ui.home

import android.arch.lifecycle.ViewModelProviders
import android.content.res.Configuration
import android.os.Bundle
import android.support.v7.app.ActionBarDrawerToggle
import android.support.v7.widget.Toolbar
import android.view.Gravity
import android.widget.ImageView
import com.alibaba.android.arouter.launcher.ARouter
import com.alibaba.android.vlayout.LayoutHelper
import com.alibaba.android.vlayout.layout.GridLayoutHelper
import com.alibaba.android.vlayout.layout.LinearLayoutHelper
import com.g.base.api.ErrorCode
import com.g.base.extend.*
import com.g.base.room.entity.UserEntity
import com.g.base.room.repository.ListStatus
import com.g.base.room.repository.Status
import com.g.base.router.BasePage
import com.g.base.ui.BaseActivity
import com.g.base.ui.BaseFragment
import com.g.base.ui.recyclerView.MultiTypeAdapter
import com.g.base.ui.recyclerView.item.BaseItem
import com.g.base.ui.recyclerView.setupRecyclerView
import io.jft.doll.R
import io.jft.doll.databinding.FragmentHomeContentBinding
import io.jft.doll.model.viewModel.HomeViewModel
import io.jft.doll.model.viewModel.RoomListViewModel
import io.jft.doll.room.entity.common.RoomCEntity
import io.jft.doll.room.entity.remote.MainBannerREntity
import io.jft.doll.router.RouterPage
import io.jft.doll.tcp.TcpHelp
import io.jft.doll.ui.home.bind.HomeImageSliderBind
import io.jft.doll.ui.home.bind.QuickButtonBind
import io.jft.doll.ui.roomList.bind.RoomItemBind

/**
 * Created by G on 2017/11/13 0013.
 */
class HomeContentFragment : BaseFragment<FragmentHomeContentBinding>() {
    override fun setContentView(): Int = R.layout.fragment_home_content
    override var hasToolbar: Boolean = true
    override var hasStatusBar: Boolean = true

    private var isAllDataSucceed = false
    private var listStatus = ListStatus.Content

    private val homeViewModel by lazy { ViewModelProviders.of(this).get(HomeViewModel::class.java) }
    private val roomListViewModel by lazy { ViewModelProviders.of(this).get(RoomListViewModel::class.java) }
    private val adapter: MultiTypeAdapter by lazy { setupRecyclerView(contentView.recyclerView) }
    private val quickButtonBind by lazy { QuickButtonBind() }
    private val slideImageBind by lazy { HomeImageSliderBind() }
    private var channelList: ArrayList<RoomCEntity> = arrayListOf()
    private var bannerList: ArrayList<MainBannerREntity> = arrayListOf()

    private val drawerLayout by lazy {
        (activity as HomeActivity).drawerLayout
    }
    private val rootDrawerToggle by lazy {
        ActionBarDrawerToggle(activity, drawerLayout, toolbar, 0, 0)
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        rootDrawerToggle.onConfigurationChanged(newConfig)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        initView()
        obsData()
        getAllData()
    }

    override fun onResume() {
        super.onResume()
        slideImageBind.parentStop = false
    }

    override fun onStop() {
        super.onStop()
        slideImageBind.parentStop = true
    }

    override fun onTokenChange(data: UserEntity?) {
        if (data == null) {
            ARouter.getInstance().build(BasePage.Oauth).navigation(activity)
            showNeedOauth()
        } else {
            getAllData()
        }
    }

    override fun onReload() {
        getAllData()
    }

    private fun initView() {
        //抽屉按钮的处理
        drawerLayout.addDrawerListener(rootDrawerToggle)
        rootDrawerToggle.syncState()

        val logoText = ImageView(activity)
        logoText.layoutParams = Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, 26.dp(), Gravity.CENTER)
        logoText.scaleType = ImageView.ScaleType.CENTER_INSIDE
        logoText.setImageResource(R.drawable.img_logo_text)
        toolbar.addView(logoText)

        toolbar.inflateMenu(R.menu.charge)
        toolbar.setOnMenuItemClickListener {
            ARouter.getInstance().build(RouterPage.RechargeActivity).navigation(activity)
            true
        }

        //上拉加载
        adapter.setOnLoadingListener {
            if (listStatus == ListStatus.Content) {
                roomListViewModel.operateRoomList(channelList.size)
                listStatus = ListStatus.LoadMore
            } else {
                adapter.setLoadingFailed()
            }
        }

        //下拉刷新
        contentView.swipeLayout.setOnRefreshListener {
            if (listStatus == ListStatus.Content) {
                roomListViewModel.operateRoomList(0)
                listStatus = ListStatus.Refreshing
            } else {
                contentView.swipeLayout.isRefreshing = false
                toast("当前正在刷新数据 请稍后再试...")
            }
        }
    }

    private fun getAllData() {
        isAllDataSucceed = false
        listStatus = ListStatus.Content
        getMainBanner()
        roomListViewModel.operateRoomList(0)
    }

    private fun getMainBanner() {
        homeViewModel.getBanner()
                .resultNotNull()
                .observeExOnce(this) {
                    when (it.status) {
                        Status.Loading -> {
                            showLoading()
                        }
                        Status.Content -> {
                            bannerList = it.data!!
                            setBannerView()
                            areAllDataGetSucceed()
                        }
                        Status.Error -> {
                            bannerList.clear()
                            showError(it.error?.message)
                        }
                    }
                }
    }

    private fun obsData() {
        setTimeout(5000L) {
            if (!isDetached && activity != null)
                homeViewModel.dailyReward((activity as BaseActivity<*>?)!!)
        }

        roomListViewModel.obsRoomList()
                .resultNotNull()
                .observeEx(this) {
                    when (it.status) {
                        Status.Loading -> {
                            if (listStatus == ListStatus.Content) {
                                showLoading()
                            }
                        }
                        Status.Content -> {
                            if (it.data!!.size < homeViewModel.roomLimit)
                                adapter.setLoadingNoMore()
                            else
                                adapter.setLoadingSucceed()

                            if (listStatus != ListStatus.LoadMore) {
                                channelList.clear()
                                contentView.swipeLayout.isRefreshing = false
                            }

                            channelList.addAll(it.data!!)
                            areAllDataGetSucceed()
                            listStatus = ListStatus.Content
                        }
                        Status.Error -> {
                            when (listStatus) {
                                ListStatus.Refreshing -> contentView.swipeLayout.isRefreshing = false
                                ListStatus.LoadMore -> if (it.error?.code == ErrorCode.EMPTY) adapter.setLoadingNoMore() else adapter.setLoadingFailed()
                                else -> {
                                    channelList.clear()
                                    showError(it.error?.message)
                                }
                            }
                            listStatus = ListStatus.Content
                        }
                    }
                }
    }

    private fun areAllDataGetSucceed() {
        if (isAllDataSucceed || channelList.isEmpty() || bannerList.isEmpty()) return
        isAllDataSucceed = true
        applyData()
        showContentView()
    }

    private fun setBannerView() {
        slideImageBind.imageSrcList = bannerList.map { it.img }
        slideImageBind.setOnClickExtListener { _, ext ->
            val url = bannerList[ext as Int].url
            if (url.isNotEmpty()) {
                ARouter.getInstance().build(RouterPage.WebViewActivity).withString("url", url).navigation(activity)
            }
        }
    }

    private fun applyData() {
        adapter.diffItems.add(slideImageBind)
        adapter.diffItems.add(quickButtonBind)
        adapter.diffItems.addAll(channelList.map(this::createRoomItemBind))

        val dp8 = 8.dp()
        adapter.layoutHelpers = arrayListOf(
                LinearLayoutHelper(0, 2) as LayoutHelper,
                GridLayoutHelper(2, channelList.size, dp8, dp8).apply {
                    setMargin(dp8, dp8, dp8, dp8)
                    setAutoExpand(false)
                } as LayoutHelper)

        adapter.calcDiffAndDispatchUpdate(
                { baseItem: BaseItem<*>, _: Int, baseItem1: BaseItem<*>, _: Int ->
                    when {
                        baseItem is HomeImageSliderBind && baseItem1 is HomeImageSliderBind -> true
                        baseItem is QuickButtonBind && baseItem1 is QuickButtonBind -> true
                        baseItem is RoomItemBind && baseItem1 is RoomItemBind -> baseItem.item.id == baseItem1.item.id
                        else -> false
                    }
                },
                { baseItem: BaseItem<*>, _: Int, baseItem1: BaseItem<*>, _: Int ->
                    when {
                        baseItem is HomeImageSliderBind && baseItem1 is HomeImageSliderBind -> true
                        baseItem is QuickButtonBind && baseItem1 is QuickButtonBind -> true
                        baseItem is RoomItemBind && baseItem1 is RoomItemBind -> baseItem.item == baseItem1.item
                        else -> false
                    }
                })
    }

    private fun createRoomItemBind(item: RoomCEntity): RoomItemBind {
        val roomItemBind = RoomItemBind(item)
        roomItemBind.setOnClickListener {
            if (it.id == R.id.button) {
                TcpHelp.appointmentRoom(item.id, !roomItemBind.item.isAppointment)
            } else {
                ARouter.getInstance().build(RouterPage.RoomActivity).withString("roomId", item.id).navigation(activity)
            }
        }
        return roomItemBind
    }
}